### =========================================================================
### I. Preparation and Settings ####
### =========================================================================

# Please set your working directory
wkpath <- ""

# Please input your species or taxa in "clades" variable to download occurrences

### For example:
### clades <- c("Ticodendraceae", "Pinus halepensis", "Castanea")
clades <- c()

### NOTICE: In GBIF, for each time you run the function occ_search(), 
###         there is a limit that max 100,000 records will be returned.
###         So if you need data of a large clade, 
###         it is recommended that you request data by genus/species.
###         Please type ?occ_search() for details.

# Please indicate output folder for the occurrences
occ.folder <- "./1_occurrences_collection/"
gbif.output <- "./1_occurrences_collection/GIBF/"
bien.output <- "./1_occurrences_collection/BIEN/"


### =========================================================================
### II. Please run following codes to get occurrences from GBIF and BIEN ####
### =========================================================================

#### 1. Preparation ####

### install packages globally
# set a local mirror server
options(repos=structure(c(CRAN="https://stat.ethz.ch/CRAN/")))

# Packages to load
packages <- c("rgbif", "BIEN")

# Install missing ones and load all packages
for (p in packages) {
  if(!library(package = p, logical.return = TRUE, character.only = TRUE)){
    install.packages(p)
    library(package = p, character.only = TRUE)
  } else {   
    library(package = p, character.only = TRUE) 
  }
}

setwd(wkpath)

if(!dir.exists(occ.folder)) {dir.create(occ.folder, recursive = T)}
if(!dir.exists(gbif.output)) {dir.create(gbif.output, recursive = T)}
if(!dir.exists(bien.output)) {dir.create(bien.output, recursive = T)}

##### 2. Get information of input clades #####

cladesKey <- c()
CladesRank <- c()
for (i in 1:length(clades)){
  bbget <- name_backbone(clades[i])
  CladesRank[i] <- tolower(bbget$rank)
  cladesKey[i] <- bbget[,paste0(CladesRank[i], "Key")]
  
}
cladesKey <- as.character(cladesKey)
CladesInfo <- data.frame(clades, CladesRank, cladesKey, stringsAsFactors = F)

##### 3. Get and save occurrences from GBIF #####

GBIFgetAll <- data.frame()
for (k in 1:length(cladesKey)){
  
  print(paste("Requesting data of", clades[k],"from GBIF."))
  
  # Get and save species occurrences and related information
  GBIFget <- occ_search(taxonKey=cladesKey[k], limit = 100000)
  saveRDS(GBIFget, file.path(gbif.output, paste0("GBIF_", clades[k], "_Key", cladesKey[k], ".rds")))
  
  GBIFgetAll <- rbind(GBIFgetAll, GBIFget$data[, c("scientificName", "decimalLongitude", "decimalLatitude")])
}

# Save only species names and coordinates for all clades in one file

colnames(GBIFgetAll) <- c("Taxon", "x", "y")
GBIFgetAll <- unique(na.omit(GBIFgetAll))
saveRDS(GBIFgetAll, file = file.path(gbif.output, "allGBIF_Occurrences.rds"))

##### 4. Get and save occurrences from BIEN #####

BIENgetAll <- data.frame()
for (b in 1:nrow(CladesInfo)){
  
  print(paste("Requesting data of", clades[b],"from BIEN."))
  
  if (CladesInfo$CladesRank[b] == "family") {
    
    BIENget <- BIEN_occurrence_family(family = CladesInfo$clades[b])
    BIENget <- BIENget[ , c("scrubbed_species_binomial", "longitude", "latitude")]
    saveRDS(BIENget, file.path(bien.output, paste0("BIEN_", clades[b], ".rds")))
    BIENgetAll <- rbind(BIENgetAll, BIENget)
    
  } else if (CladesInfo$CladesRank[b] == "genus") {
    
    BIENget <- BIEN_occurrence_genus(genus = CladesInfo$clades[b])
    BIENget <- BIENget[ , c("scrubbed_species_binomial", "longitude", "latitude")]
    saveRDS(BIENget, file.path(bien.output, paste0("BIEN_", clades[b], ".rds")))
    BIENgetAll <- rbind(BIENgetAll, BIENget)
  
    }  else if (CladesInfo$CladesRank[b] == "species") {
    
      BIENget <- BIEN_occurrence_species(species = CladesInfo$clades[b])
      BIENget <- BIENget[ , c("scrubbed_species_binomial", "longitude", "latitude")]
      saveRDS(BIENget, file.path(bien.output, paste0("BIEN_", clades[b], ".rds")))
      BIENgetAll <- rbind(BIENgetAll, BIENget)
      
    } else {
      
    cat(paste("WARNING: \n Data for", b, CladesInfo$clades[b],"is not downloaded, \n please use family/genus/species-level taxon to get data from BIEN."))
      
    }
  }

# Save only species names and coordinates for all clades in one file
colnames(BIENgetAll) <- c("Taxon", "x", "y")
BIENgetAll_clean <- unique(na.omit(BIENgetAll))
saveRDS(BIENgetAll_clean, file = file.path(bien.output, "allBIEN_Occurrences.rds"))

##### 5. Save all occurrences from both GBIF and BIEN in one file #####
occ.all <- na.omit(rbind(GBIFgetAll, BIENgetAll_clean))
occ.all$x <- round(occ.all$x,3)
occ.all$y <- round(occ.all$y,3)
occ.all <- unique(occ.all)
saveRDS(occ.all, file = file.path(occ.folder, "allGBIFandBIEN_Occurrences.rds"))
